package implementation1.app.commands;

import exceptions.CommandErrorFromUserException;
import exceptions.CommandException;
import exceptions.StreamEOFException;
import exceptions.StreamException;
import implementation1.app.Global;
import implementation1.app.streams.AccessAttributes;
import implementation1.data.states.RunningStatus;
import implementation1.data.states.WaitingStatus;
import interfaces.app.IProcess;
import interfaces.data.IHandle;

/**
 * Class for handle of command "exit" for stopping parent process.
 * Created: 22.10.11
 *
 * @author Jan Svab
 */
public class Exit extends Command
{
    /**
     * Default constructor.
     *
     * @param parent parent process over which is command processed
     * @param handle parameters of command
     */
    public Exit(IProcess parent, IHandle handle)
    {
        super(parent, handle);
    }

    /**
     * Main method for processing of command.
     *
     * @param args arguments of command
     * @throws CommandException Thrown if occurs an error during processing of the command.
     */
    @Override
    public void mainCommand(String[] args) throws CommandException
    {
        if (args != null && args.length != 0)
        {
            throw new CommandErrorFromUserException(bundle.getString("error.arguments.wrongCount"));
        }

        if (handle.getOut() == null)
        {
            throw new CommandException(bundle.getString("error.outputStream.empty"));
        }

        if (handle.getIn() == null)
        {
            throw new CommandException(bundle.getString("error.inputStream.empty"));
        }

        try
        {
            handle.getIn().open(AccessAttributes.READ);
            openedStreamsOfProcess.add(handle.getIn());
            handle.getOut().open(AccessAttributes.WRITE);
            openedStreamsOfProcess.add(handle.getOut());

            handle.getOut().writeLine(bundle.getString("message.exit.question"));

            String answer = null;
            try
            {
                this.status = new WaitingStatus();
                answer = handle.getIn().readLine().trim();
            } catch (StreamEOFException e)
            {
                throw new CommandErrorFromUserException(bundle.getString("error.unexpectedAnswer"));
            } finally
            {
                this.status = new RunningStatus();
            }
            if (answer.equals("y"))
            {
                if (!parentProcess.quit())
                {
                    parentProcess.terminate();
                }
            }
            else if (!answer.equals("n"))
            {
                throw new CommandErrorFromUserException(bundle.getString("error.unexpectedAnswer"));
            }

        } catch (StreamException e)
        {
            throw new CommandException(e.getMessage());
        } finally
        {
            Global.closeStreamQuietly(handle.getIn());
            Global.closeStreamQuietly(handle.getOut());

            openedStreamsOfProcess.remove(handle.getOut());
            openedStreamsOfProcess.remove(handle.getIn());
        }
    }

    @Override
    public String toString()
    {
        return "exit";
    }
}
